<template>
<div class="out-box">
    <h1 class="map-title">Leaflet 深圳市路网: 中心坐标={{ mapCenter }}, zoom缩放级别={{ mapZoom }}</h1>
    <div class="map-container">
        <div id="map"></div>
    </div>
    <el-form class="route-query-form" :inline="true" size="small"
             ref="nodeQueryFormRef" :model="routeQueryForm" :rules="rules"
             hide-required-asterisk
             label-width="auto" label-suffix=":">
        <el-form-item label="起点编号" prop="startingNode">
            <el-input class="node-num-input"
                      v-model="routeQueryForm.startingNode"
                      oninput="value = value.replace(/\D/g, '')"
                      type="text" maxlength="12">
            </el-input>
        </el-form-item>
        <el-form-item label="终点编号" prop="destinationNode">
            <el-input class="node-num-input"
                      v-model="routeQueryForm.destinationNode"
                      oninput="value = value.replace(/\D/g, '')"
                      type="text" maxlength="12">
            </el-input>
        </el-form-item>
        <el-form-item>
            <el-button type="primary" @click="submitForm('nodeQueryFormRef')" icon="el-icon-search">查询</el-button>
            <el-button type="plain" @click="resetForm('nodeQueryFormRef')" icon="el-icon-circle-close">清空</el-button>
        </el-form-item>
    </el-form>
</div>
</template>

<script>
import * as L from 'leaflet'

const IMAGE_PATH = '/static/images'
L.Icon.Default.imagePath = IMAGE_PATH + '/'
// const MARKER_ICON_URL = path.join(IMAGE_PATH, 'marker-icon.png')
// const MARKER_SHADOW_URL = path.join(IMAGE_PATH, 'marker-shadow.png')

/**
 * 四舍五入保留 n 位小数
 *
 * @param x 做近似处理的数
 * @param n 小数点后保留 n 位, n必须为整数
 * @returns string
 */
let roundN = (x, n) => {
    let k = Math.pow(10, n)
    let y = Math.round(x * k) / k;
    return y.toFixed(n)
}

export default {
    name: 'MapDemo1',
    data() {
        return {
            map: null,
            mapCenter: [22.538, 113.977], // 深圳世界之窗附近, 经纬度坐标(北纬22.54,东经113.98附近)
            mapZoom: 15,
            // XYZ 切片形式的地图 URL 地址
            url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
            attr: 'OSM地图（仅供测试参考，严禁用于商业用途！）&copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap contributors</a>',
            // url: 'https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetGray/MapServer/tile/{z}/{y}/{x}',
            // attr: 'ArcGIS 黑白影像',
            // url: 'http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}',
            // attr: '高德地图（©2021 高德软件 GS(2019)6379号 - 甲测资字11002004 - 京ICP证 070711号）',
            routeQueryForm: {
                startingNode: '45268',
                destinationNode: '43427',
            },
            rules: {
                startingNode: [
                    { required: true, message: '必须输入起点编号', trigger: 'blur' },
                    { max: 12, message: '编号长度超上限', trigger: 'change' },
                ],
                destinationNode: [
                    { required: true, message: '必须输入终点编号', trigger: 'blur' },
                    { max: 12, message: '编号长度超上限', trigger: 'change' },
                ],
            },
            geometryList: [{
                "type": "LineString",
                "coordinates": [[113.9, 22.5], [113.90, 22.6], [114.0, 22.7]]
            }, {
                "type": "LineString",
                "coordinates": [[113.8, 22.5], [113.80, 22.6], [113.9, 22.7]]
            },
            ],
            pathLayer: null
        }
    },
    computed: {
    },
    methods: {
        submitForm(formName) {
            const _this = this;
            _this.$refs[formName].validate((valid) => {
                if (!valid) {
                    console.log('Error: form validate failed!')
                    return false
                }
                console.log(_this.routeQueryForm)
                let requestBody = {
                    "startingNode": _this.routeQueryForm.startingNode,
                    "destinationNode": _this.routeQueryForm.destinationNode,
                }
                axios.post('/api/routing/getShortestPath', requestBody).then((resp) => {
                    if (resp.data === null || resp.data.msg !== 'OK') {
                        console.log('Error axios post')
                        console.log(resp)
                        return
                    }
                    //
                    // console.log(resp)
                    // _this.$alert('起点'+_this.routeQueryForm.startingNode+'查询成功!', '成功', {
                    //     confirmButtonText: '确定',
                    //     callback: action => {
                    //         _this.$router.push('/MapDemo1')
                    //     }
                    // })
                    _this.geometryList = resp.data.geometryList
                    _this.pathLayer.clearLayers()
                    _this.pathLayer.addData(_this.geometryList)
                })
            })
        },
        resetForm(formName) {
            console.log('正在清空' + formName)
            this.routeQueryForm.startingNode = '';
            this.routeQueryForm.destinationNode = '';
        },
    },
    created() {
    },
    mounted() {
        let map5 = L.map("map", {
            minZoom: 3,
            maxZoom: 18,
            center: this.mapCenter,
            zoom: this.mapZoom,
            zoomControl: false,
            crs: L.CRS.EPSG3857
        });
        const mapOptions = {
            attribution: this.attr,
        }
        let _this = this
        let updateCurrCoordinate = function(e) {
            console.log(e)
            if (_this.map === null) {
                return
            }
            const center = _this.map.getCenter()
            const x = center.lat.toFixed(4)
            const y = center.lng.toFixed(4)
            _this.mapCenter = [Number(x), Number(y)]
            _this.mapZoom = _this.map.getZoom()
        }
        map5.on('moveend', updateCurrCoordinate)
        L.tileLayer(this.url, mapOptions).addTo(map5);

        //-----
        let cbFunctionOnEachFeature = (feature, layer) => {
            let popupContent =
                "<p>Feature type: '" + feature.geometry.type + "'</p>"
            if (feature.properties && feature.properties.popupContent) {
                popupContent = feature.properties.popupContent + popupContent
            }
            if (feature.geometry.type === "Point") {
                let coordinates = feature.geometry.coordinates
                let longitude = roundN(coordinates[0], 3)
                let latitude = roundN(coordinates[1], 3)
                popupContent += "<p>坐标：北纬/东经=["
                    + latitude + ", " + longitude
                    + "]</p>"
            }
            layer.bindPopup(popupContent)
        }
        //---------------
        let geojsonFeature = {
            "type": "Feature",
            "properties": {
                "name": "深圳世界之窗",
                "amenity": "展馆",
                "popupContent": "<h3>世界之窗</h3><p>地址: 广东省深圳市南山区深南大道9037号</p>"
            },
            "geometry": {
                "type": "Point",
                "coordinates": [113.969642, 22.537545]
            }
        };
        let defaultOptions = {
            pointToLayer: function (feature, latLng) {
                return L.circleMarker(latLng, {
                    radius: 8,
                    fillColor: '#ff7800',
                    color: '#000',
                    weight: 1,
                    opacity: 1,
                    fillOpacity: 0.5
                });
            },
            onEachFeature: cbFunctionOnEachFeature
        }
        let myLayer1 = L.geoJSON(null, defaultOptions).addTo(map5)
        myLayer1.addData(geojsonFeature)

        //-------------------
        // let myLineStings = [{
        //     "type": "LineString",
        //     "coordinates": [[113.9, 22.5], [113.90, 22.6], [114.0, 22.7]]
        // }, {
        //     "type": "LineString",
        //     "coordinates": [[113.8, 22.5], [113.80, 22.6], [113.9, 22.7]]
        // }];
        let myLineStyle = {
            "color": "#0000ff",
            "weight": 5,
            "opacity": 0.65
        };
        this.pathLayer = L.geoJSON(null, {style: myLineStyle}).addTo(map5);

        //-------------------
        let states = [{
            "type": "Feature",
            "properties": {"party": "蓝色地块"},
            "geometry": {
                "type": "Polygon",
                "coordinates": [[
                    [113.9, 22.40],
                    [113.9, 22.45],
                    [113.925, 22.46],
                    [113.95, 22.45],
                    [113.95, 22.40],
                ]]
            }
        }, {
            "type": "Feature",
            "properties": {"party": "红色地块"},
            "geometry": {
                "type": "Polygon",
                "coordinates": [[
                    [114.01, 22.40],
                    [114.0, 22.45],
                    [114.025, 22.46],
                    [114.05, 22.45],
                    [114.04, 22.40],
                ]]
            }
        }];

        L.geoJSON(states, {
            style: (feature) => {
                switch (feature.properties.party) {
                    case '红色地块': return {color: "#ff0000"};
                    case '蓝色地块': return {color: "#0000ff"};
                }
            }
        }).addTo(map5);
        this.map = map5;
    }
}
</script>

<style lang="stylus" scoped>
@import 'leaflet/dist/leaflet.css'
.out-box
    height: 100vh
.node-num-input
    width: 100px
.map-title
    height: 30px
.map-container
    width: 100%
    height: calc(100vh - 65px)
    #map
        width: 100%
        height: 100%
</style>
